/**
 *	@file	pm_radio.c
 *	@brief	金銀　ラジオデータコントロール
 *	@author	Miyuki Iwasawa
 *	@date	07.10.18
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/palanm.h"
#include "system/wipe.h"
#include "system/buflen.h"
#include "system/pm_rtc.h"
#include "gflib/touchpanel.h"
#include "application/app_tool.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_pg_radio.h"
#include "field/situation.h"

#if GS_BTS5545_20090710_FIX
#include "field/player.h"
#endif

#include "pm_radio.h"

#define WORDSET_RADIO_BUFLEN	((18*2)+EOM_SIZE)	//1ライン分
#define WORDSET_RADIO_BNUM		(8)
#define BUFLEN_RADIO_LINE		(18*2+EOM_SIZE)
#define BUFLEN_RADIO_MSG		((18*30)*2+EOM_SIZE)	//30行まで保障

static void PMRadio_CurrentProgramInfoPut(PM_RADIO_MAN* wk);

static const PMRADIO_SEQ_TBL radio_program[RADIO_PROG_MAX] = {
 //ベーシックチャンネル
 {RadioMusic_Init,RadioMusic_Play,RadioMusic_End},

 //ポケモンチャンネル
 {RadioKouza_Init,RadioKouza_Play,RadioKouza_End},

 //バラエティ
 {RadioSearch_Init,RadioSearch_Play,RadioSearch_End},
 {RadioDrama_Init,RadioDrama_Play,RadioDrama_End},
 {RadioAoi_Init,RadioAoi_Play,RadioAoi_End},
 //街角チャンネル
 {RadioTrainerP_Init,RadioTrainerP_Play,RadioTrainerP_End},
 {RadioMachiHito_Init,RadioMachiHito_Play,RadioMachiHito_End},

 //特殊チャンネル
 {RadioPoke_Init,RadioPoke_Play,RadioPoke_End},
 {RadioAlf_Init,RadioAlf_Play,RadioAlf_End},
 {RadioRocket_Init,RadioRocket_Play,RadioRocket_End},
 {RadioAjito_Init,RadioAjito_Play,RadioAjito_End},
 {RadioCM_Init,RadioCM_Play,RadioCM_End},
};



#if GS_BTS5545_20090710_FIX
PLAYER_SAVE_DATA* Situation_GetPlayerSaveData(SITUATION *st);

extern u16* Situation_GetBGMWork(SITUATION * st);
/**
 *	@brief	ラジオデータのコントロールマネージャを作成
 *
 *	@param	save	セーブデータへのポインタ
 *	@param	zone_id	自機が今居るゾーン
 *	@param	field_zone	自機のフィールド位置上のゾーン
 *	@param	win	ラジオメッセージを表示する初期化済みウィンドウへのポインタ
 *	@param	col	メッセージの描画色
 *	@param	heapID	ワークを確保するheapID
 */
PM_RADIO_MAN* PMRadio_Init(SAVEDATA* save,int zone_id,int field_zone,BOOL is_kanto,
		GF_BGL_BMPWIN* win,GF_BGL_BMPWIN* win_title,GF_BGL_BMPWIN* win_dj,GF_PRINTCOLOR col,int heapID)
{
	SITUATION *st    = SaveData_GetSituation( save );
	PLAYER_SAVE_DATA *ps = Situation_GetPlayerSaveData(st);
	u16 *bgmno       = Situation_GetBGMWork(st);
	PM_RADIO_MAN* wk;

	wk = sys_AllocMemory(heapID,sizeof(PM_RADIO_MAN));
	MI_CpuClear8(wk,sizeof(PM_RADIO_MAN));

	//引継ぎパラメータセット
	wk->save = save;
	wk->zone_id = zone_id;
	wk->field_zone = field_zone;
	wk->is_kanto_f = is_kanto;

	wk->win = win;
	wk->win_title = win_title;
	wk->win_dj = win_dj;
	wk->col = col;

	wk->f_col = GF_PRINTCOLOR_GET_LETTER(wk->col);
	wk->s_col = GF_PRINTCOLOR_GET_SHADOW(wk->col);
	wk->b_col = GF_PRINTCOLOR_GET_GROUND(wk->col);

	wk->heapID = heapID;

	wk->msgMan = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,NARC_msg_pg_radio_dat,wk->heapID);

	//ワードセット領域作成
	wk->wset = WORDSET_CreateEx(WORDSET_RADIO_BNUM,WORDSET_RADIO_BUFLEN,wk->heapID);
	//1行分のテンポラリバッファ生成
	wk->str_tmp = STRBUF_Create(BUFLEN_RADIO_LINE,wk->heapID);
	wk->str_title = STRBUF_Create(BUFLEN_RADIO_LINE,wk->heapID);
	wk->str_dj = STRBUF_Create(BUFLEN_RADIO_LINE,wk->heapID);

	//カレント文字列の格納バッファ
	wk->c_str = STRBUF_Create(BUFLEN_RADIO_MSG,wk->heapID);
	wk->c_str_tmp = STRBUF_Create(BUFLEN_RADIO_MSG,wk->heapID);

	// 自転車に乗っているときはBGMワークのクリアをしない
	if(Player_SaveDataFormGet(ps)!=HERO_FORM_CYCLE){
		// フィールドBGM保存処理の破棄
		*bgmno = 0;
	}
	return wk;
}

#elif GS_BTS5519_20090708_FIX

extern u16* Situation_GetBGMWork(SITUATION * st);
/**
 *	@brief	ラジオデータのコントロールマネージャを作成
 *
 *	@param	save	セーブデータへのポインタ
 *	@param	zone_id	自機が今居るゾーン
 *	@param	field_zone	自機のフィールド位置上のゾーン
 *	@param	win	ラジオメッセージを表示する初期化済みウィンドウへのポインタ
 *	@param	col	メッセージの描画色
 *	@param	heapID	ワークを確保するheapID
 */
PM_RADIO_MAN* PMRadio_Init(SAVEDATA* save,int zone_id,int field_zone,BOOL is_kanto,
		GF_BGL_BMPWIN* win,GF_BGL_BMPWIN* win_title,GF_BGL_BMPWIN* win_dj,GF_PRINTCOLOR col,int heapID)
{
	SITUATION *st    = SaveData_GetSituation( save );
	u16 *bgmno       = Situation_GetBGMWork(st);
	PM_RADIO_MAN* wk;

	wk = sys_AllocMemory(heapID,sizeof(PM_RADIO_MAN));
	MI_CpuClear8(wk,sizeof(PM_RADIO_MAN));

	//引継ぎパラメータセット
	wk->save = save;
	wk->zone_id = zone_id;
	wk->field_zone = field_zone;
	wk->is_kanto_f = is_kanto;

	wk->win = win;
	wk->win_title = win_title;
	wk->win_dj = win_dj;
	wk->col = col;

	wk->f_col = GF_PRINTCOLOR_GET_LETTER(wk->col);
	wk->s_col = GF_PRINTCOLOR_GET_SHADOW(wk->col);
	wk->b_col = GF_PRINTCOLOR_GET_GROUND(wk->col);

	wk->heapID = heapID;

	wk->msgMan = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,NARC_msg_pg_radio_dat,wk->heapID);

	//ワードセット領域作成
	wk->wset = WORDSET_CreateEx(WORDSET_RADIO_BNUM,WORDSET_RADIO_BUFLEN,wk->heapID);
	//1行分のテンポラリバッファ生成
	wk->str_tmp = STRBUF_Create(BUFLEN_RADIO_LINE,wk->heapID);
	wk->str_title = STRBUF_Create(BUFLEN_RADIO_LINE,wk->heapID);
	wk->str_dj = STRBUF_Create(BUFLEN_RADIO_LINE,wk->heapID);

	//カレント文字列の格納バッファ
	wk->c_str = STRBUF_Create(BUFLEN_RADIO_MSG,wk->heapID);
	wk->c_str_tmp = STRBUF_Create(BUFLEN_RADIO_MSG,wk->heapID);

	// フィールドBGM保存処理の破棄
	*bgmno = 0;

	return wk;
}

#else

/**
 *	@brief	ラジオデータのコントロールマネージャを作成
 *
 *	@param	save	セーブデータへのポインタ
 *	@param	zone_id	自機が今居るゾーン
 *	@param	field_zone	自機のフィールド位置上のゾーン
 *	@param	win	ラジオメッセージを表示する初期化済みウィンドウへのポインタ
 *	@param	col	メッセージの描画色
 *	@param	heapID	ワークを確保するheapID
 */
PM_RADIO_MAN* PMRadio_Init(SAVEDATA* save,int zone_id,int field_zone,BOOL is_kanto,
		GF_BGL_BMPWIN* win,GF_BGL_BMPWIN* win_title,GF_BGL_BMPWIN* win_dj,GF_PRINTCOLOR col,int heapID)
{
	PM_RADIO_MAN* wk;

	wk = sys_AllocMemory(heapID,sizeof(PM_RADIO_MAN));
	MI_CpuClear8(wk,sizeof(PM_RADIO_MAN));

	//引継ぎパラメータセット
	wk->save = save;
	wk->zone_id = zone_id;
	wk->field_zone = field_zone;
	wk->is_kanto_f = is_kanto;

	wk->win = win;
	wk->win_title = win_title;
	wk->win_dj = win_dj;
	wk->col = col;

	wk->f_col = GF_PRINTCOLOR_GET_LETTER(wk->col);
	wk->s_col = GF_PRINTCOLOR_GET_SHADOW(wk->col);
	wk->b_col = GF_PRINTCOLOR_GET_GROUND(wk->col);

	wk->heapID = heapID;

	wk->msgMan = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,NARC_msg_pg_radio_dat,wk->heapID);

	//ワードセット領域作成
	wk->wset = WORDSET_CreateEx(WORDSET_RADIO_BNUM,WORDSET_RADIO_BUFLEN,wk->heapID);
	//1行分のテンポラリバッファ生成
	wk->str_tmp = STRBUF_Create(BUFLEN_RADIO_LINE,wk->heapID);
	wk->str_title = STRBUF_Create(BUFLEN_RADIO_LINE,wk->heapID);
	wk->str_dj = STRBUF_Create(BUFLEN_RADIO_LINE,wk->heapID);

	//カレント文字列の格納バッファ
	wk->c_str = STRBUF_Create(BUFLEN_RADIO_MSG,wk->heapID);
	wk->c_str_tmp = STRBUF_Create(BUFLEN_RADIO_MSG,wk->heapID);

	return wk;
}


#endif
/**
 *	@brief	ラジオデータコントロールマネージャの破棄
 *
 */
void PMRadio_Release(PM_RADIO_MAN* wk)
{
	STRBUF_Delete(wk->c_str_tmp);
	STRBUF_Delete(wk->c_str);
	STRBUF_Delete(wk->str_dj);
	STRBUF_Delete(wk->str_title);
	STRBUF_Delete(wk->str_tmp);
	WORDSET_Delete(wk->wset);

	MSGMAN_Delete(wk->msgMan);

	MI_CpuClear8(wk,sizeof(PM_RADIO_MAN));
	sys_FreeMemoryEz(wk);
}

/**
 *	@brief	チャンネルIDから現在再生されるプログラムNoを取得
 */
static u8 pmradio_GetProgramFromChID(PM_RADIO_MAN* man,PM_RADIO_CHID ch_id)
{
	if(ch_id >= RADIO_CH_MAX){
		ch_id = 0;
	}
	if(man->cm_req_f){
		man->cm_req_f = FALSE;
		return RADIO_PROG_CM;
	}
	//現在時刻
	GF_RTC_GetDateTime(&man->date, &man->time);

	//本当は現在時刻などを評価して再生プログラムNoを返す
	switch(ch_id){
	case RADIO_CH_MUSIC:
		return RADIO_PROG_MUSIC;
	case RADIO_CH_POKEMON:
		return RADIO_PROG_KOUZA;
	case RADIO_CH_TOWN:
		return RADIO_PROG_TRAINERP+(man->time.hour%2);
	case RADIO_CH_MULTI:
		return RADIO_PROG_SEARCH+(man->time.hour%3);
	case RADIO_CH_POKE:
		return RADIO_PROG_POKE;
	case RADIO_CH_ALF:
		return RADIO_PROG_ALF;
	case RADIO_CH_ROCKET:
		return RADIO_PROG_ROCKET;
	case RADIO_CH_AJITO:
		return RADIO_PROG_AJITO;
	}
	return RADIO_PROG_MUSIC;
}

/**
 *	@brief	ラジオ　番組初期化
 *
 *	@param	prog_id	再生したいチャンネルID
 *	@param	level	初期再生パワー PMRADIO_REC_NORMAL:強、PMRADIO_REC_FEEBLE:弱
 */
void PMRadio_ProgramCall(PM_RADIO_MAN* wk,PM_RADIO_CHID ch_id,PMRADIO_REC_LEVEL level)
{
	wk->fst_f = FALSE;

	if(ch_id >= RADIO_CH_MAX){
		ch_id = 0;
	}
	wk->ch_id = ch_id;
	if(wk->prog_id != RADIO_PROG_CM){
		wk->old_prog_id = wk->prog_id;
	}
	wk->prog_id = pmradio_GetProgramFromChID(wk,ch_id);
	wk->seq = 0;
	wk->msg_wait = 45;
	wk->mwait_ct = 0;
	wk->scroll_ct = 8;
	wk->swait_ct = 0;
	wk->rec_lv_f = level;
	wk->program_end_f = FALSE;

#if GS_BTS5504_20090707_FIX
	wk->sub_seq = 0;	//BTS5504修正 090707
#endif

#ifdef PM_DEBUG
	if(sys.cont & PAD_BUTTON_R){
		wk->msg_wait = 4;
		wk->scroll_ct = 4;
	}
#endif

	if((wk->prog_id != RADIO_PROG_CM) && (wk->old_prog_id != wk->prog_id)){
		wk->pass_work = 0;
	}
	GF_BGL_BmpWinDataFill(wk->win,(wk->b_col << 4)|wk->b_col);
	GF_BGL_BmpWinOn(wk->win);

	(radio_program[wk->prog_id].call_func)(wk);
	PMRadio_CurrentProgramInfoPut(wk);
}

/**
 *	@brief	ラジオ　番組再生終了
 */
void PMRadio_ProgramEnd(PM_RADIO_MAN* man)
{
	if(man->ch_wk != NULL){
		(radio_program[man->prog_id].end_func)(man);
	}

	GF_BGL_BmpWinDataFill(man->win,(man->b_col << 4)|man->b_col);
	GF_BGL_BmpWinOn(man->win);

	man->cm_req_f = FALSE;
}

/**
 *	@brief	ラジオ　電波の強さ変更
 */
void PMRadio_ReceptLevelChange(PM_RADIO_MAN* wk,PMRADIO_REC_LEVEL level)
{
	wk->rec_lv_f = level;
}


/**
 *	@brief	メッセージスクロール
 */
BOOL RadioSub_MsgWaitScroll(PM_RADIO_MAN* man)
{
	if(man->mwait_ct < man->msg_wait){
		++man->mwait_ct;
		return FALSE;
	}
	GF_BGL_BmpWinShift( man->win, GF_BGL_BMPWIN_SHIFT_U,2,0x00);
	GF_BGL_BmpWinOn(man->win);
	if(man->swait_ct++ < 8){
		return FALSE;
	}
	man->swait_ct = 0;
	man->mwait_ct = 0;
	return TRUE;
}
BOOL RadioSub_MsgScroll(PM_RADIO_MAN* man)
{
	GF_BGL_BmpWinShift( man->win, GF_BGL_BMPWIN_SHIFT_U,2,0x00);
	GF_BGL_BmpWinOn(man->win);
	if(man->swait_ct++ < man->scroll_ct){
		return FALSE;
	}
	man->swait_ct = 0;
	return TRUE;

}
/**
 *	@brief	タイムウェイト
 */
BOOL RadioSub_TimeWait(PM_RADIO_MAN* man)
{
	if(man->mwait_ct++ < man->msg_wait){
		return FALSE;
	}
	man->mwait_ct = 0;
	return TRUE;
}

/**
 *	@brief	ラジオ　番組再生
 *
 *	@li	メインで呼んでください
 */
void PMRadio_ProgramMain(PM_RADIO_MAN* man)
{
	int ret;

	switch(man->seq){
	case 0:
		man->seq = radio_program[man->prog_id].main_func(man);
		break;
	case 1:	//プログラム停止
		(radio_program[man->prog_id].end_func)(man);
		man->scroll_ct = 16;
		man->msg_wait = 15;
		man->seq++;
		break;
	case 2:
		if(!RadioSub_MsgScroll(man)){
			return;
		}
		man->seq++;
		break;
	case 3:
		if(!RadioSub_TimeWait(man)){
			return;
		}
		PMRadio_ProgramCall(man,man->ch_id,man->rec_lv_f);	//プログラム再抽選
		man->seq = 0;
		break;
	}
}

/**
 *	@brief	ラジオ　カレントチャンネルプログラムのタイトルとDJネームを出力
 */
static void PMRadio_CurrentProgramInfoPut(PM_RADIO_MAN* wk)
{
	GF_BGL_BmpWinDataFill(wk->win_title,0x00);
	GF_BGL_BmpWinDataFill(wk->win_dj,0x00);

	GF_STR_PrintColor(wk->win_title,FONT_SYSTEM,wk->str_title,
		0,0,MSG_NO_PUT,GF_PRINTCOLOR_MAKE(1,2,0),NULL );
	GF_STR_PrintColor(wk->win_dj,FONT_SYSTEM,wk->str_dj,
		0,0,MSG_NO_PUT,GF_PRINTCOLOR_MAKE(1,2,0),NULL );

	GF_BGL_BmpWinOnVReq(wk->win_title);
	GF_BGL_BmpWinOnVReq(wk->win_dj);
}

/**
 *	@brief	文字列の行単位描画
 */
static void radiosub_LinePut(PM_RADIO_MAN* man,STRBUF* str,u8 line)
{
	if(man->rec_lv_f == PMRADIO_REC_FEEBLE){
		STRBUF_PMRADIO_OverwriteDot(str,70);
	}
	GF_STR_PrintColor( man->win,FONT_SYSTEM,str,
						0,line*16,MSG_NO_PUT,man->col,NULL );
}

/**
 *	@brief	STRBUF型文字列を受け取り、行単位で描画する
 */
int RadioSub_StrWriteSet(PM_RADIO_MAN* man,const STRBUF* str)
{
	man->line_ct = 0;
	man->line_max = STRBUF_GetLines(str);

	//文字列コピー
	STRBUF_Copy( man->c_str, str);

	STRBUF_CopyLine(man->str_tmp,str,man->line_ct++);
	radiosub_LinePut(man,man->str_tmp,man->fst_f);

	GF_BGL_BmpWinOn(man->win);

	if(man->line_ct >= man->line_max){	//一行文字列
		man->next_seq = RADIO_MSEQ_STR_INIT;
		return RADIO_MSEQ_TIME_WAIT;	//タイムウェイト
	}
	if(man->fst_f){
		man->next_seq = RADIO_MSEQ_STR_PLAY;
		return RADIO_MSEQ_SCROLL_WAIT;
	}
	man->next_seq = RADIO_MSEQ_STR_PLAY;
	return RADIO_MSEQ_TIME_WAIT;
}

/**
 *	@brief	STRBUF型文字列を受け取り、行単位で描画する
 */
int RadioSub_StrWrite(PM_RADIO_MAN* man)
{
	if(!man->fst_f){
		man->fst_f = TRUE;	//初回メッセージ描画済みフラグOn
	}
	STRBUF_CopyLine(man->str_tmp,man->c_str,man->line_ct++);
	radiosub_LinePut(man,man->str_tmp,1);

	GF_BGL_BmpWinOn(man->win);
	if(man->line_ct >= man->line_max){
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	一文再生
 */
//void RadioSub_SentencePlayEx(PM_RADIO_MAN* man,const STRBUF* str,BOOL line_mode)
void RadioSub_SentencePlayEx(PM_RADIO_MAN* man,u16 str_id,BOOL line_mode)
{
	man->line_mode = line_mode;
	MSGMAN_GetString(man->msg_prog,str_id,man->c_str_tmp);
	WORDSET_ExpandStr(man->wset,man->c_str,man->c_str_tmp);

	man->line_ct = 0;
	man->line_max = STRBUF_GetLines(man->c_str);
	man->line_seq = 0;

	//文字列コピー
//	STRBUF_Copy( man->c_str, str);

	STRBUF_CopyLine(man->str_tmp,man->c_str,man->line_ct++);
	radiosub_LinePut(man,man->str_tmp,man->fst_f);

	GF_BGL_BmpWinOn(man->win);

	if(man->line_ct >= man->line_max){	//一行文字列
		man->line_seq = RADIO_MSEQ_END_WAIT;
		return;
	}
	if(!man->fst_f){	//タイトルコール
		man->line_seq = RADIO_MSEQ_TIME_WAIT;
	}else{	//それ以外
		man->line_seq = RADIO_MSEQ_SCROLL_WAIT;
	}
}

/**
 *	@brief	一文再生 gmmid指定
 */
void RadioSub_SentencePlay(PM_RADIO_MAN* man,u16 str_id)
{
	RadioSub_SentencePlayEx(man,str_id,FALSE);
#if 0
	man->line_mode = FALSE;
	MSGMAN_GetString(man->msg_prog,str_id,man->c_str);
	WORDSET_ExpandStr(man->wset,man->c_str_tmp,man->c_str);

	RadioSub_SentencePlayBuf(man,man->c_str_tmp);
#endif
}

/**
 *	@brief	一文再生アイキャッチモード(最終ラインをスクロールしない) gmmid指定
 */
void RadioSub_EyeCatchPlay(PM_RADIO_MAN* man,u16 str_id)
{

	RadioSub_SentencePlay(man,str_id);

	man->line_mode = TRUE;
	man->program_end_f = TRUE;

	//ジングル再生
	PMGS_StopRadio( 0 );				// ラジオ再生関数に変えた
	PMGS_PlayRadio( RADIO_ME_JINGLE );

}


/**
 *	@brief	一文再生
 */
int RadioSub_SentencePlayWait(PM_RADIO_MAN* man)
{
	switch(man->line_seq){
	case RADIO_MSEQ_STR_PLAY:
		if(RadioSub_StrWrite(man)){
			if(man->line_mode){
				man->line_seq = RADIO_MSEQ_END;
			}else{
				man->line_seq = RADIO_MSEQ_END_SCROLL;
			}
			break;
		}
		man->line_seq = RADIO_MSEQ_SCROLL_WAIT;
		break;
	case RADIO_MSEQ_SCROLL_WAIT:
		if(RadioSub_MsgWaitScroll(man)){
			man->line_seq = RADIO_MSEQ_STR_PLAY;
		}
		break;
	case RADIO_MSEQ_TIME_WAIT:
		if(RadioSub_TimeWait(man)){
			man->line_seq = RADIO_MSEQ_STR_PLAY;
		}
		break;
	case RADIO_MSEQ_END_SCROLL:
		if(!RadioSub_MsgWaitScroll(man)){
			break;
		}
		man->line_seq = RADIO_MSEQ_END;
		break;
	case RADIO_MSEQ_END_WAIT:
		if(!RadioSub_TimeWait(man)){
			break;
		}
		//ここは流れる
	case RADIO_MSEQ_END:
		man->line_seq = 0;
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	最後の一行スクロールアウト
 */
int RadioSub_EyeCatchPlayWait(PM_RADIO_MAN* man)
{
	switch(man->sub_seq){
	case 0:
		if(!RadioSub_SentencePlayWait(man)){
			break;
		}
		man->sub_seq++;
		break;
	case 1:
		// RADIO_ME_JINGLEの再生終了を待っている
		if(PMGS_RadioPlayCheck()){
			break;
		}
		man->sub_seq = 0;
		return TRUE;
	}
	return FALSE;
}
